package com.efast.dmom.aps.service.impl;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.efast.dmom.aps.bean.PlanOrder;
import com.efast.dmom.aps.bean.ProductRoute;
import com.efast.dmom.aps.bean.ProductionLine;
import com.efast.dmom.aps.bean.ResultBean;
import com.efast.dmom.aps.bean.Shift;
import com.efast.dmom.aps.bean.ShiftItem;
import com.efast.dmom.aps.bean.WorkingCalendar;
import com.efast.dmom.aps.bean.Workshop;
import com.efast.dmom.aps.constant.ServiceConstants;
import com.efast.dmom.aps.datahandlers.PlanOrderDataHandler;
import com.efast.dmom.aps.datahandlers.PlanScheduleDataHandler;
import com.efast.dmom.aps.datahandlers.ProductRouteDataHandler;
import com.efast.dmom.aps.datahandlers.ProductionLineDataHandler;
import com.efast.dmom.aps.datahandlers.WorkCalendarDataHandler;
import com.efast.dmom.aps.datahandlers.WorkShopDataHandler;
import com.efast.dmom.aps.entity.PlanOrderEntity;
import com.efast.dmom.aps.entity.PlanOrderScheduleInfoEntity;
import com.efast.dmom.aps.service.PlanOrderScheduleService;
import com.efast.dmom.aps.service.WorkingCalendarService;
import com.efast.dmom.aps.util.TimeUtil;

/**
 * @author Aaron Liu
 * @Creation Time：2020年2月7日 上午10:32:12
 */

@Service
public class PlanOrderScheduleServiceImpl implements PlanOrderScheduleService {

	@Autowired
	private PlanScheduleDataHandler scheduleDataHandler = null;

	@Autowired
	private WorkingCalendarService calendarService = null;
	@Autowired
	private PlanOrderDataHandler planOrderDataHandler;
	@Autowired
	private WorkCalendarDataHandler workCalendarDataHandler;

	@Autowired
	private WorkShopDataHandler workShopDataHandler;

	@Autowired
	private ProductionLineDataHandler productionLineDataHandler;

	@Autowired
	private ProductRouteDataHandler pRouteDataHandler;

	public PlanOrderScheduleServiceImpl() {

	}

	@Override
	public ResultBean autoSchedule(List<PlanOrder> orderList) {

		ResultBean resultBean = new ResultBean(true);

		if (orderList == null || orderList.size() < 0) {
			resultBean.setSuccess(false);
			return resultBean;
		}

		resultBean = validateOrders(orderList);
		if (!resultBean.isSuccess()) {
			return resultBean;
		}
		
		long routeKey = 0;
		long defaultPKey = 0;
		
		for(PlanOrder planOrder : orderList){
			
			PlanOrderEntity planOrderEntity = planOrder.getInnerData();
			
			if(planOrderEntity == null){
				continue;
			}

			ProductRoute pRoute = pRouteDataHandler.getProductRouteRel(planOrderEntity.getPartNo(),
					planOrderEntity.getPartRevision());

			if (pRoute == null || pRoute.getInnerData() == null || pRoute.getInnerData().getId() <= 0) {

				resultBean.setSuccess(false);
				resultBean.setMessage("没有找到物料号： " + planOrderEntity.getPartNo() + " 对应的工艺");
				return resultBean;
			}
			routeKey = pRoute.getInnerData().getRouteId();
			
			if(planOrderEntity.getProdLineId() > 0){
				defaultPKey = planOrderEntity.getProdLineId();
			}
			else {
				defaultPKey = scheduleDataHandler.getDefaultProdLineKey(routeKey);
				if (defaultPKey <= 0) {

					resultBean.setSuccess(false);
					resultBean.setMessage("没有找到工艺路线： " + pRoute.getInnerData().getName() + " 对应的默认产线");
					return resultBean;
				}
			}
			
			List<PlanOrder> toScheduleList = new ArrayList<PlanOrder>();
			toScheduleList.add(planOrder);
			
			List<PlanOrder> unBroadcastOrders = scheduleDataHandler
					.getUnbroadcastPlanOrder(defaultPKey);
			if (unBroadcastOrders != null) {

				for (PlanOrder order : unBroadcastOrders) {

					if (!toScheduleList.contains(order)) {
						toScheduleList.add(order);
					}
				}
			}
			
			resultBean = doSchedule(routeKey, defaultPKey, toScheduleList);
			if(! resultBean.isSuccess()){
				return resultBean;
			}
		}
		
		return resultBean;
	}

	private ResultBean doSchedule(long routeKey, long defaultPKey, List<PlanOrder> orderList) {

		ResultBean resultBean = new ResultBean(true);

		if (orderList.size() <= 0) {
			resultBean.setSuccess(false);
			return resultBean;
		}

		Collections.sort(orderList, PlanOrder.timeComparator);

		LocalDate earliestTime = TimeUtil.getLocalDateTime().toLocalDate();
		LocalDate latestTime = orderList.get(orderList.size() - 1).getInnerData().getPlanOfflineDate();

		List<PlanOrderScheduleInfoEntity> infoList = new ArrayList<PlanOrderScheduleInfoEntity>();

		List<PlanOrderScheduleInfoEntity> result = getScheduleInfo(orderList.get(0).getInnerData(), defaultPKey,
				routeKey, earliestTime, latestTime);

		if (result != null && result.size() > 0) {
			infoList.addAll(result);
		}

		Collections.sort(orderList, PlanOrder.productionComparator);

		LocalDateTime lastScheduledTime = null;

		for (int i = 0; i < orderList.size(); i++) {

			PlanOrderEntity entity = orderList.get(i).getInnerData();

			lastScheduledTime = checkCapacity(routeKey, defaultPKey, lastScheduledTime, infoList, entity);

			if (lastScheduledTime == null) {

				resultBean.setSuccess(false);
				resultBean.setMessage("无法获取计划工单：【" + entity.getOrderNumber() + "】的上线时间，请检查工作日历配置");

				return resultBean;
			}
		}
		scheduleDataHandler.savePlanOrderInfo(orderList);
		scheduleDataHandler.saveScheduledInfo(infoList);

		return resultBean;
	}

	private LocalDateTime checkCapacity(long routeKey, long pLineKey, LocalDateTime lastScheduledTime,
			List<PlanOrderScheduleInfoEntity> infoList, PlanOrderEntity orderEntity) {

		double scheduleCounter = 0;
		double orderQuantity = orderEntity.getQuantity();

		for (int i = 0; i < infoList.size(); i++) {

			PlanOrderScheduleInfoEntity scheduleInfo = infoList.get(i);

			double scheduledCount = scheduleInfo.getScheduledCount();
			double capacity = scheduleInfo.getCapacity();

			if (scheduledCount >= capacity) {
				continue;
			}

			if (scheduleInfo.getShiftItems().size() == 0) {
				return null;
			}

			if (capacity - scheduledCount > 0) {

				if (lastScheduledTime == null) {

					lastScheduledTime = scheduleInfo.getLastScheduledTime();

					if (lastScheduledTime == null) {
						lastScheduledTime = toDateTime(scheduleInfo.getScheduleDate(),
								scheduleInfo.getShiftItems().get(0).getInnerEntity().getStartTime());
					}

					scheduleInfo.setLastScheduledTime(lastScheduledTime);
					orderEntity.setScheudledOnlineDate(lastScheduledTime);
				}

				double calcSum = scheduleCounter;
				scheduleCounter = capacity - scheduledCount + scheduleCounter;

				if (orderQuantity <= scheduleCounter) {

					scheduleInfo.setScheduledCount(scheduledCount + (orderQuantity - calcSum));

					boolean isFullCapacity = false;
					if (i > 0) {
						PlanOrderScheduleInfoEntity previousDay = infoList.get(i - 1);
						isFullCapacity = previousDay.isFullCapacity();
					}

					return fixOfflineDateTime(routeKey, pLineKey, calcSum, isFullCapacity, lastScheduledTime,
							orderEntity, scheduleInfo);
				} else {
					scheduleInfo.setScheduledCount(capacity);
				}
			} else {
				scheduleInfo.setScheduledCount(capacity);
				scheduleCounter = scheduleCounter + capacity;
			}
		}
		return null;
	}

	private LocalDateTime fixOfflineDateTime(long routeKey, long pLineKey, double calcSum, boolean isFullCapacity,
			LocalDateTime lastScheduledTime, PlanOrderEntity orderEntity, PlanOrderScheduleInfoEntity scheduleInfo) {

		double shiftCalcSum = 0;
		boolean lastScheduleTimeSet = false;

		List<ShiftItem> itemList = scheduleInfo.getShiftItems();

		for (int i = 0; i < itemList.size(); i++) {

			LocalDateTime shiftStartTime = toDateTime(scheduleInfo.getScheduleDate(),
					itemList.get(i).getInnerEntity().getStartTime());
			LocalDateTime shiftEndTime = toDateTime(scheduleInfo.getScheduleDate(),
					itemList.get(i).getInnerEntity().getEndTime());

			if (!lastScheduleTimeSet) {

				if ((lastScheduledTime.equals(shiftStartTime) || lastScheduledTime.isAfter(shiftStartTime))
						&& lastScheduledTime.isBefore(shiftEndTime)) {

					shiftStartTime = lastScheduledTime;
					orderEntity.setScheudledOnlineDate(lastScheduledTime);
					lastScheduleTimeSet = true;
				}

				if (lastScheduledTime.isBefore(shiftStartTime)) {

					if (isFullCapacity) {
						lastScheduledTime = shiftStartTime;
					}

					orderEntity.setScheudledOnlineDate(lastScheduledTime);
					lastScheduleTimeSet = true;
				}
			}

			if (lastScheduleTimeSet) {

				double shiftCapacity = getCapacity(routeKey, pLineKey, shiftStartTime, shiftEndTime);
				double previousCalcSum = shiftCalcSum;

				shiftCalcSum = shiftCalcSum + shiftCapacity;

				if ((calcSum + shiftCalcSum) >= orderEntity.getQuantity()) {

					LocalDateTime orderFinishTime = shiftStartTime.plusMinutes(
							(long) (getOrderCostTime(routeKey, pLineKey, orderEntity.getQuantity() - calcSum - previousCalcSum)
									* 60));

					orderEntity.setScheudledOfflineDate(orderFinishTime);
					scheduleInfo.setLastScheduledTime(orderFinishTime);

					if (orderFinishTime != null && i == itemList.size() - 1 && orderFinishTime.equals(shiftEndTime)) {
						scheduleInfo.setFullCapacity(true);
					}

					return orderFinishTime;
				}
			}
		}
		return null;
	}

	private LocalDateTime toDateTime(LocalDate dateTime, LocalTime time) {

		return LocalDateTime.of(dateTime.getYear(), dateTime.getMonth(), dateTime.getDayOfMonth(), time.getHour(),
				time.getMinute(), 0);
	}

	private List<PlanOrderScheduleInfoEntity> getScheduleInfo(PlanOrderEntity orderEntity, long lineKey, long routeKey,
			LocalDate earliestTime, LocalDate latestTime) {

		List<PlanOrderScheduleInfoEntity> infoList = new ArrayList<PlanOrderScheduleInfoEntity>();

		scheduleDataHandler.setPlantShopId(orderEntity);

		Map<LocalDate, WorkingCalendar> detailsMap = calendarService.getWorkingHoursPerDay(orderEntity.getPlantId(),
				orderEntity.getShopId(), lineKey, earliestTime, latestTime);

		for (Map.Entry<LocalDate, WorkingCalendar> entry : detailsMap.entrySet()) {

			PlanOrderScheduleInfoEntity infoEntity = new PlanOrderScheduleInfoEntity();

			WorkingCalendar calendar = entry.getValue();

			infoEntity.setPlanOrderId(orderEntity.getId());
			infoEntity.setCapacity(calendar.getTotalHours() * getProdLineCapacity(routeKey, lineKey));
			infoEntity.setProdLineKey(orderEntity.getProdLineId());
			infoEntity.setScheduleDate(entry.getKey());
			infoEntity.setShopId(orderEntity.getShopId());
			infoEntity.setPlantId(orderEntity.getPlantId());
			List<ShiftItem> shiftItems = new ArrayList<ShiftItem>();

			List<Shift> shiftList = calendar.getShiftList();
			for (Shift shift : shiftList) {
				List<ShiftItem> itemList = shift.getShiftItems();
				shiftItems.addAll(itemList);
			}

			Collections.sort(shiftItems, ShiftItem.sequenceComparator);

			infoEntity.setShiftItems(shiftItems);

			infoList.add(infoEntity);
		}

		Collections.sort(infoList, PlanOrderScheduleInfoEntity.timeASC);

		return infoList;
	}

	private double getCapacity(long routeKey, long prodLineId, LocalDateTime startTime, LocalDateTime endTime) {

		// get production line capacity:
		double plineCapacity = getProdLineCapacity(routeKey, prodLineId);

		Duration duration = Duration.between(startTime, endTime);
		return (((double) duration.getSeconds()) / 3600d) * ((double) plineCapacity);
	}

	// Aaron Liu: TODO
	private int getProdLineCapacity(long pLineKey) {

		return scheduleDataHandler.getProdLineCapacity(pLineKey);
	}

	private double getProdLineCapacity(long routeKey, long pLineKey) {

		return scheduleDataHandler.getProdLineCapacity(routeKey, pLineKey);
	}

	private double getOrderCostTime(long routeKey, long pLineKey, double prodCounter) {

		// get production line capacity:
		double capacity = (double) (getProdLineCapacity(routeKey, pLineKey));
		if (capacity <= 0) {
			return 0d;
		}
		return 1d / capacity * (double) (prodCounter);
	}

	private ResultBean validateOrders(List<PlanOrder> orderList) {

		ResultBean resultBean = new ResultBean(true);

		for (PlanOrder order : orderList) {

			PlanOrderEntity entity = order.getInnerData();

			if (entity.getPlanOfflineDate() == null) {
				resultBean.setSuccess(false);
				resultBean.setMessage("请维护计划【" + entity.getOrderNumber() + "】的计划下线时间");
				return resultBean;
			}

			if (entity.getOrderStatus() > ServiceConstants.APS_PLAN_ORDER_STATUS_BROADCAST) {
				resultBean.setSuccess(false);
				resultBean.setMessage("计划【" + entity.getOrderNumber() + "】为已下发状态的计划，不可以再次进行排产");
				return resultBean;
			}

			LocalDate offLineDate = entity.getPlanOfflineDate();
			if (offLineDate.isBefore(LocalDate.now())) {
				resultBean.setSuccess(false);
				resultBean.setMessage("计划【" + entity.getOrderNumber() + "】计划下线时间早于当前时间,请重新配置计划下线时间");
				return resultBean;
			}

			if (entity.getProdLineId() == 0) {

				resultBean.setSuccess(false);
				resultBean.setMessage("计划【" + entity.getOrderNumber() + "】没有指定产线信息");
				return resultBean;
			}
		}
		return resultBean;
	}

	@Override
	public ResultBean manualSchedule(PlanOrder planOrder) {
		ResultBean resultBean = new ResultBean(true, ' ');
		/**
		 * 1.判断线别是不是变更 1.1线别没有变更 1.1.1开始时间提前
		 * 1.1.1.1该计划工单前面有计划工单，上一个计划工单默认排到当前工单后面，当前工单后面的按顺序向后排
		 * 1.1.1.2该计划工单前面没有计划工单，该工单后面的计划工单都向前提 1.1.2开始时间推后
		 * 1.1.2.1该计划工单后面有计划工单，后面所有的计划工单依次向后推 1.1.2.2该计划工单后面没有计划工单，不需要处理
		 * 1.2线别有变更 1.2.1原来线别的工单都向前提 1.2.2当前时间是否有工单在生产
		 * 1.2.2.1有工单生产，之前的工单排在该工单后面，工单向后依次推 1.2.2.2没有工单，该工单后面的工单，依次向后
		 */

		PlanOrderEntity innerData = planOrder.getInnerData();

		if (innerData == null) {
			resultBean.setSuccess(false);
			resultBean.setMessage("所传的计划工单信息缺失!");
			return resultBean;
		}

		long id = innerData.getId();
		PlanOrder planOrderOld = planOrderDataHandler.getById(id);
		if (planOrderOld == null) {
			resultBean.setSuccess(false);
			resultBean.setMessage("所传的计划工单ID异常!");
			return resultBean;
		}
		// 旧的上线时间
		LocalDateTime scheudledOnlineDate2 = planOrderOld.getInnerData().getScheudledOnlineDate();

		// 调整后的上线时间
		LocalDateTime scheudledOnlineDate = planOrder.getInnerData().getScheudledOnlineDate();

		long prodLineId = innerData.getProdLineId();
		long prodLineId2 = planOrderOld.getInnerData().getProdLineId();

		// 防止传入信息不全
		planOrder = planOrderDataHandler.getById(id);
		planOrder.getInnerData().setScheudledOnlineDate(scheudledOnlineDate);

		if (prodLineId != prodLineId2) {
			ProductionLine pLine = productionLineDataHandler.getById(prodLineId);
			if (pLine == null) {
				resultBean.setSuccess(false);
				resultBean.setMessage("所传的产线ID异常!");
				return resultBean;
			}
			long workshopId = pLine.getInnerData().getWorkshopId();
			Workshop workshop = workShopDataHandler.getById(workshopId);
			if (workshop == null) {
				resultBean.setSuccess(false);
				resultBean.setMessage("所传的产线ID异常,无对应的车间!");
				return resultBean;
			}
			Long plantId = workshop.getInnerData().getPlantId();
			planOrder.getInnerData().setPlantId(plantId);
			planOrder.getInnerData().setShopId(workshopId);
		}

		// 判断产品，产线，工艺路径是否能够匹配

		// 判断上线时间是否有班次
		// 1.判断线别是不是变更
		if (prodLineId == prodLineId2) {

			// 1.1线别没有变更

			// 1.1.1开始时间提前
			if (scheudledOnlineDate.isBefore(scheudledOnlineDate2)) {

				LocalDateTime scheudledOfflineDate2 = planOrderOld.getInnerData().getScheudledOfflineDate();

				// 原计划工单后面的计划工单
				List<PlanOrder> listPlanOrdersAfterList = planOrderDataHandler.getByLineAndTime(prodLineId,
						scheudledOfflineDate2, null);
				// 原计划工单调整后，在原计划工单前面的计划工单，不包含开始时间小于scheudledOnlineDate，结束时间大于scheudledOnlineDate的计划
				List<PlanOrder> listPlanOrdersBeforeList = planOrderDataHandler.getByLineAndTime(prodLineId,
						scheudledOnlineDate, scheudledOnlineDate2);
				// 原计划工单调整后，开始时间介于某个工单开始结束之间的工单
				PlanOrder middlePlanOrder = planOrderDataHandler.getMiddlePlanOrderByLineAndTime(prodLineId,
						scheudledOnlineDate);

				// 1.1.1.1该计划工单前面有计划工单，上一个计划工单默认排到当前工单后面，当前工单后面的按顺序向后排
				ResultBean result = setScheduleOffline(planOrder);

				if (result.isSuccess()) {
					planOrder = (PlanOrder) result.getObject();
				} else {
					resultBean.setSuccess(false);
					resultBean.setMessage(planOrder.getInnerData().getOrderNumber() + "无法获取下线时间");
					return resultBean;
				}

				planOrderDataHandler.update(planOrder);

				LocalDateTime sDateTime = planOrder.getInnerData().getScheudledOfflineDate();

				if (middlePlanOrder != null) {

					middlePlanOrder.getInnerData().setScheudledOnlineDate(sDateTime);
					result = setScheduleOffline(middlePlanOrder);

					if (result.isSuccess()) {
						middlePlanOrder = (PlanOrder) result.getObject();
					} else {
						resultBean.setSuccess(false);
						resultBean.setMessage(middlePlanOrder.getInnerData().getOrderNumber() + "无法获取下线时间");
						return resultBean;
					}

					planOrderDataHandler.update(middlePlanOrder);
					sDateTime = middlePlanOrder.getInnerData().getScheudledOfflineDate();

				}

				for (PlanOrder po : listPlanOrdersBeforeList) {
					if (po.getInnerData().getId() == planOrder.getInnerData().getId()) {
						continue;
					}

					po.getInnerData().setScheudledOnlineDate(sDateTime);
					result = setScheduleOffline(po);
					if (result.isSuccess()) {
						po = (PlanOrder) result.getObject();
					} else {
						resultBean.setSuccess(false);
						resultBean.setMessage(po.getInnerData().getOrderNumber() + "无法获取下线时间");
						return resultBean;
					}
					planOrderDataHandler.update(po);
					sDateTime = po.getInnerData().getScheudledOfflineDate();
				}

				for (PlanOrder po : listPlanOrdersAfterList) {
					po.getInnerData().setScheudledOnlineDate(sDateTime);

					result = setScheduleOffline(po);
					if (result.isSuccess()) {
						po = (PlanOrder) result.getObject();
					} else {
						resultBean.setSuccess(false);
						resultBean.setMessage(po.getInnerData().getOrderNumber() + "无法获取下线时间");
						return resultBean;
					}

					planOrderDataHandler.update(po);
					sDateTime = po.getInnerData().getScheudledOfflineDate();
				}

			} else {
				// 1.1.2开始时间推后
				LocalDateTime scheudledOfflineDate2 = planOrderOld.getInnerData().getScheudledOfflineDate();
				List<PlanOrder> listPlanOrdersAfterList = planOrderDataHandler.getByLineAndTime(prodLineId,
						scheudledOfflineDate2, null);

				// 计算下线时间，保存
				ResultBean result = setScheduleOffline(planOrder);

				if (result.isSuccess()) {
					planOrder = (PlanOrder) result.getObject();
				} else {
					resultBean.setSuccess(false);
					resultBean.setMessage(planOrder.getInnerData().getOrderNumber() + "无法获取下线时间");
					return resultBean;
				}

				planOrderDataHandler.update(planOrder);

				// 改计划工单后面的计划工单依次向后推算
				LocalDateTime sDateTime = planOrder.getInnerData().getScheudledOfflineDate();
				for (PlanOrder po : listPlanOrdersAfterList) {
					po.getInnerData().setScheudledOnlineDate(sDateTime);

					result = setScheduleOffline(po);
					if (result.isSuccess()) {
						po = (PlanOrder) result.getObject();
					} else {
						resultBean.setSuccess(false);
						resultBean.setMessage(po.getInnerData().getOrderNumber() + "无法获取下线时间");
						return resultBean;
					}

					planOrderDataHandler.update(po);
					sDateTime = po.getInnerData().getScheudledOfflineDate();
				}
			}
		} else {
			// 1.2线别有变更
			// 原来线别，该工单后面的计划工单
			LocalDateTime oldOnlineDateTime = planOrderOld.getInnerData().getScheudledOnlineDate();
			List<PlanOrder> listPlanOrdersAfterList = planOrderDataHandler.getByLineAndTime(prodLineId2,
					oldOnlineDateTime, null);

			// 1.2.1原来线别的工单都向前提
			LocalDateTime sDateTime = oldOnlineDateTime;
			for (PlanOrder po : listPlanOrdersAfterList) {
				po.getInnerData().setScheudledOnlineDate(sDateTime);

				ResultBean result = setScheduleOffline(po);
				if (result.isSuccess()) {
					po = (PlanOrder) result.getObject();
				} else {
					resultBean.setSuccess(false);
					resultBean.setMessage(po.getInnerData().getOrderNumber() + "无法获取下线时间");
					return resultBean;
				}
				planOrderDataHandler.update(po);
				sDateTime = po.getInnerData().getScheudledOfflineDate();
			}

			// 原计划工单后面的计划工单
			List<PlanOrder> listPlanOrdersAfterList2 = planOrderDataHandler.getByLineAndTime(prodLineId,
					scheudledOnlineDate, null);
			// 原计划工单调整后，开始时间介于某个工单开始结束之间的工单
			PlanOrder middlePlanOrder = planOrderDataHandler.getMiddlePlanOrderByLineAndTime(prodLineId,
					scheudledOnlineDate);

			ResultBean result = setScheduleOffline(planOrder);

			if (result.isSuccess()) {
				planOrder = (PlanOrder) result.getObject();
			} else {
				resultBean.setSuccess(false);
				resultBean.setMessage(planOrder.getInnerData().getOrderNumber() + "无法获取下线时间");
				return resultBean;
			}
			planOrderDataHandler.update(planOrder);

			LocalDateTime sDateTime2 = planOrder.getInnerData().getScheudledOfflineDate();

			if (middlePlanOrder != null) {
				middlePlanOrder.getInnerData().setScheudledOnlineDate(sDateTime2);

				result = setScheduleOffline(middlePlanOrder);

				if (result.isSuccess()) {
					middlePlanOrder = (PlanOrder) result.getObject();
				} else {
					resultBean.setSuccess(false);
					resultBean.setMessage(middlePlanOrder.getInnerData().getOrderNumber() + "无法获取下线时间");
					return resultBean;
				}

				planOrderDataHandler.update(middlePlanOrder);
				sDateTime2 = middlePlanOrder.getInnerData().getScheudledOfflineDate();
			}

			for (PlanOrder po : listPlanOrdersAfterList2) {
				po.getInnerData().setScheudledOnlineDate(sDateTime2);

				result = setScheduleOffline(po);
				if (result.isSuccess()) {
					po = (PlanOrder) result.getObject();
				} else {
					resultBean.setSuccess(false);
					resultBean.setMessage(po.getInnerData().getOrderNumber() + "无法获取下线时间");
					return resultBean;
				}
				planOrderDataHandler.update(po);
				sDateTime2 = po.getInnerData().getScheudledOfflineDate();
			}
		}

		resultBean.setSuccess(true);
		resultBean.setMessage("手动调整成功!");
		return resultBean;
	}

	// 计算下线时间
	public ResultBean setScheduleOffline(PlanOrder po) {
		ResultBean resultBean = new ResultBean(true, "");

		// po里面必须包含数量，产线id，上线时间，route
		long prodLineId = po.getInnerData().getProdLineId();
		// PlanOrderEntity应该有route字段，现在缺失
		// line 和route配置有节拍\
		// 目前是固定节拍，是不准确的
		int jph = getProdLineCapacity(prodLineId);
		if (jph < 1) {
			resultBean.setSuccess(true);
			resultBean.setMessage("产线产能设置异常");
			return resultBean;
		}

		LocalDateTime scheudledOnlineDate = po.getInnerData().getScheudledOnlineDate();
		int productTime = po.getInnerData().getQuantity() * 60 / jph; // 生产用时

		// 计算下线时间

		ResultBean offlineDate2 = getOfflineDate(prodLineId, scheudledOnlineDate, productTime);
		LocalDateTime offlineDate = null;
		if (offlineDate2.isSuccess()) {

			offlineDate = (LocalDateTime) offlineDate2.getObject();

			po.getInnerData().setScheudledOfflineDate(offlineDate);
			resultBean.setSuccess(true);
			resultBean.setObject(po);
		} else {
			resultBean.setSuccess(false);
			resultBean.setMessage(offlineDate2.getMessage());

		}
		return resultBean;
	}

	// 计算下线时间
	public ResultBean getOfflineDate(long lineId, LocalDateTime scheudledOnlineDate, int productTime) {
		/**
		 * 常见班次： 单班次 (1)08:00--17:00 (1)08:30--17:30 (1)09:00--18:00
		 * (1)08:00--20:00 双班次： (1)07:00--19:00 (2)19:00--07:00 (1)08:00--20:00
		 * (2)20:00--08:00 (1)07:00--16:00 (2)16:00--01:00 (1)07:00--15:00
		 * (2)15:00--23:00 三班次： (1)08:00--16:00 (2)16:00--00:00 (3)00:00--08:00
		 * (1)00:00--08:00 (2)08:00--16:00 (3)16:00--00:00
		 * 
		 */
		ResultBean resultBean = new ResultBean(true, "");
		LocalDate localDate = scheudledOnlineDate.toLocalDate();

		List<Shift> listShifts = workCalendarDataHandler.getShiftByLineAndTime(lineId, localDate);
		if (listShifts == null) {
			resultBean.setSuccess(false);
			resultBean.setMessage(localDate + "休息或者没有配置工作日历!");
			return resultBean;
		} else if (listShifts.size() == 1) {

			Shift shift = listShifts.get(0);
			LocalTime shiftStart = shift.getInnnerData().getStartTime();
			LocalTime shiftEnd = shift.getInnnerData().getEndTime();
			LocalDateTime shiftStartTime = LocalDateTime.of(localDate, shiftStart);
			LocalDateTime shiftEndTime = LocalDateTime.of(localDate, shiftEnd);
			// 理论不存在
			if (shiftEndTime.isBefore(shiftStartTime)) {
				shiftEndTime = shiftEndTime.plusDays(1);
			}

			if (scheudledOnlineDate.isBefore(shiftStartTime)) {
				ResultBean result = getOfflineFromShift(shift, shiftStartTime, shiftEndTime, shiftStartTime,
						productTime);
				if (result.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(result.getObject());
				} else {
					productTime = (int) result.getObject();
					ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
					if (nextResult.isSuccess()) {
						resultBean.setSuccess(true);
						resultBean.setObject(nextResult.getObject());
					} else {
						resultBean.setSuccess(false);
						resultBean.setMessage("无法获取下线时间");
					}
				}

			} else if (scheudledOnlineDate.isAfter(shiftStartTime) && scheudledOnlineDate.isBefore(shiftEndTime)) {
				ResultBean result = getOfflineFromShift(shift, shiftStartTime, shiftEndTime, scheudledOnlineDate,
						productTime);
				if (result.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(result.getObject());
				} else {
					productTime = (int) result.getObject();
					ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
					if (nextResult.isSuccess()) {
						resultBean.setSuccess(true);
						resultBean.setObject(nextResult.getObject());
					} else {
						resultBean.setSuccess(false);
						resultBean.setMessage("无法获取下线时间");
					}
				}
			} else {
				ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
				if (nextResult.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(nextResult.getObject());
				} else {
					resultBean.setSuccess(false);
					resultBean.setMessage("无法获取下线时间");
				}
			}

		} else if (listShifts.size() == 2) {
			// 双班次默认是连续的
			/**
			 * 双班次： (1)07:00--19:00 (2)19:00--07:00 (1)08:00--20:00
			 * (2)20:00--08:00 (1)07:00--16:00 (2)16:00--01:00 (1)07:00--15:00
			 * (2)15:00--23:00
			 */

			Shift shift1 = listShifts.get(0);
			LocalTime shift1Start = shift1.getInnnerData().getStartTime();
			LocalTime shift1End = shift1.getInnnerData().getEndTime();
			LocalDateTime shift1StartTime = LocalDateTime.of(localDate, shift1Start);
			LocalDateTime shift1EndTime = LocalDateTime.of(localDate, shift1End);
			// 理论不存在
			if (shift1EndTime.isBefore(shift1StartTime)) {
				resultBean.setSuccess(false);
				resultBean.setMessage(localDate + "首班次跨天!");
				return resultBean;
			}

			Shift shift2 = listShifts.get(1);
			LocalTime shift2Start = shift2.getInnnerData().getStartTime();
			LocalTime shift2End = shift2.getInnnerData().getEndTime();
			LocalDateTime shift2StartTime = LocalDateTime.of(localDate, shift2Start);
			LocalDateTime shift2EndTime = LocalDateTime.of(localDate, shift2End);
			// 第二班次存在跨天的可能性
			if (shift2EndTime.isBefore(shift2StartTime)) {
				shift2EndTime = shift2EndTime.plusDays(1);
			}

			// 第一个班次，开始生产
			if (scheudledOnlineDate.isAfter(shift1StartTime) && scheudledOnlineDate.isBefore(shift1EndTime)) {
				ResultBean result = getOfflineFromShift(shift1, shift1StartTime, shift1EndTime, scheudledOnlineDate,
						productTime);
				if (result.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(result.getObject());
				} else {
					productTime = (int) result.getObject();
					ResultBean result2 = getOfflineFromShift(shift2, shift2StartTime, shift2EndTime, shift2StartTime,
							productTime);
					if (result2.isSuccess()) {
						resultBean.setSuccess(true);
						resultBean.setObject(result2.getObject());
					} else {
						productTime = (int) result2.getObject();
						ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
						if (nextResult.isSuccess()) {
							resultBean.setSuccess(true);
							resultBean.setObject(nextResult.getObject());
						} else {
							resultBean.setSuccess(false);
							resultBean.setMessage("无法获取下线时间");
						}
					}
				}
			} else if (scheudledOnlineDate.isAfter(shift2StartTime) && scheudledOnlineDate.isBefore(shift2EndTime)) {
				ResultBean result = getOfflineFromShift(shift2, shift2StartTime, shift2EndTime, scheudledOnlineDate,
						productTime);
				if (result.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(result.getObject());
				} else {
					productTime = (int) result.getObject();
					ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
					if (nextResult.isSuccess()) {
						resultBean.setSuccess(true);
						resultBean.setObject(nextResult.getObject());
					} else {
						resultBean.setSuccess(false);
						resultBean.setMessage("无法获取下线时间");
					}
				}
			} else {
				ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
				if (nextResult.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(nextResult.getObject());
				} else {
					resultBean.setSuccess(false);
					resultBean.setMessage("无法获取下线时间");
				}
			}
		} else if (listShifts.size() == 3) {
			/**
			 * 三班次： (1)08:00--16:00 (2)16:00--00:00 (3)00:00--08:00
			 * (1)00:00--08:00 (2)08:00--16:00 (3)16:00--00:00
			 */

			Shift shift1 = listShifts.get(0);
			LocalTime shift1Start = shift1.getInnnerData().getStartTime();
			LocalTime shift1End = shift1.getInnnerData().getEndTime();
			LocalDateTime shift1StartTime = LocalDateTime.of(localDate, shift1Start);
			LocalDateTime shift1EndTime = LocalDateTime.of(localDate, shift1End);
			// 理论不存在
			if (shift1EndTime.isBefore(shift1StartTime)) {
				resultBean.setSuccess(false);
				resultBean.setMessage(localDate + "首班次跨天!");
				return resultBean;
			}

			Shift shift2 = listShifts.get(1);
			LocalTime shift2Start = shift2.getInnnerData().getStartTime();
			LocalTime shift2End = shift2.getInnnerData().getEndTime();
			LocalDateTime shift2StartTime = LocalDateTime.of(localDate, shift2Start);
			LocalDateTime shift2EndTime = LocalDateTime.of(localDate, shift2End);
			// 第二班次存在跨天的可能性
			if (shift2EndTime.isBefore(shift2StartTime)) {
				shift2EndTime = shift2EndTime.plusDays(1);
			}

			Shift shift3 = listShifts.get(2);
			LocalTime shift3Start = shift3.getInnnerData().getStartTime();
			LocalTime shift3End = shift3.getInnnerData().getEndTime();
			LocalDateTime shift3StartTime = LocalDateTime.of(localDate, shift3Start);
			LocalDateTime shift3EndTime = LocalDateTime.of(localDate, shift3End);

			// 判断第三班次开始时间是否小于第二班次开始时间
			if (shift3StartTime.isBefore(shift2StartTime)) {
				shift3StartTime = shift3StartTime.plusDays(1);
			}

			// 第三班次存在跨天的可能性
			if (shift3EndTime.isBefore(shift3StartTime)) {
				shift3EndTime = shift3EndTime.plusDays(1);
			}

			// 第一个班次，开始生产
			if (scheudledOnlineDate.isAfter(shift1StartTime) && scheudledOnlineDate.isBefore(shift1EndTime)) {

				ResultBean result = getOfflineFromShift(shift1, shift1StartTime, shift1EndTime, scheudledOnlineDate,
						productTime);
				if (result.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(result.getObject());
				} else {
					productTime = (int) result.getObject();
					// 第2个班次继续生产
					ResultBean result2 = getOfflineFromShift(shift2, shift2StartTime, shift2EndTime, shift2StartTime,
							productTime);
					if (result2.isSuccess()) {
						resultBean.setSuccess(true);
						resultBean.setObject(result2.getObject());
					} else {
						productTime = (int) result2.getObject();
						// 第三个班次继续生产
						ResultBean result3 = getOfflineFromShift(shift3, shift3StartTime, shift3EndTime,
								shift3StartTime, productTime);
						if (result3.isSuccess()) {
							resultBean.setSuccess(true);
							resultBean.setObject(result3.getObject());
						} else {
							productTime = (int) result.getObject();
							// 下一个班次继续生产
							ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
							if (nextResult.isSuccess()) {
								resultBean.setSuccess(true);
								resultBean.setObject(nextResult.getObject());
							} else {
								resultBean.setSuccess(false);
								resultBean.setMessage("无法获取下线时间");
							}
						}
					}
				}

			} else if (scheudledOnlineDate.isAfter(shift2StartTime) && scheudledOnlineDate.isBefore(shift2EndTime)) {

				ResultBean result = getOfflineFromShift(shift2, shift2StartTime, shift2EndTime, scheudledOnlineDate,
						productTime);
				if (result.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(result.getObject());
				} else {
					productTime = (int) result.getObject();

					// 第三个班次继续生产
					ResultBean result3 = getOfflineFromShift(shift3, shift3StartTime, shift3EndTime, shift3StartTime,
							productTime);

					if (result3.isSuccess()) {
						resultBean.setSuccess(true);
						resultBean.setObject(result3.getObject());
					} else {
						productTime = (int) result.getObject();
						// 下一个班次继续生产
						ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
						if (nextResult.isSuccess()) {
							resultBean.setSuccess(true);
							resultBean.setObject(nextResult.getObject());
						} else {
							resultBean.setSuccess(false);
							resultBean.setMessage("无法获取下线时间");
						}
					}
				}
			} else {

				ResultBean result = getOfflineFromShift(shift3, shift3StartTime, shift3EndTime, scheudledOnlineDate,
						productTime);
				if (result.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(result.getObject());
				} else {
					productTime = (int) result.getObject();
					// 下一个班次继续生产
					ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
					if (nextResult.isSuccess()) {
						resultBean.setSuccess(true);
						resultBean.setObject(nextResult.getObject());
					} else {
						resultBean.setSuccess(false);
						resultBean.setMessage("无法获取下线时间");
					}
				}
			}
		}
		return resultBean;

	}

	// 从下一天
	public ResultBean getOfflineFromNextDate(long lineId, LocalDate nextDate, int productTime) {

		ResultBean resultBean = new ResultBean(true, "");
		LocalDate localDate = nextDate;

		List<Shift> listShifts = workCalendarDataHandler.getShiftByLineAndTime(lineId, nextDate);
		if (listShifts == null) {

			resultBean.setSuccess(false);
			resultBean.setMessage(nextDate + "休息或者没有配置工作日历!");
			return resultBean;

		} else if (listShifts.size() == 1) {

			Shift shift = listShifts.get(0);
			LocalTime shiftStart = shift.getInnnerData().getStartTime();
			LocalTime shiftEnd = shift.getInnnerData().getEndTime();
			LocalDateTime shiftStartTime = LocalDateTime.of(localDate, shiftStart);
			LocalDateTime shiftEndTime = LocalDateTime.of(localDate, shiftEnd);
			// 理论不存在
			if (shiftEndTime.isBefore(shiftStartTime)) {
				shiftEndTime = shiftEndTime.plusDays(1);
			}

			ResultBean result = getOfflineFromShift(shift, shiftStartTime, shiftEndTime, shiftStartTime, productTime);
			if (result.isSuccess()) {
				resultBean.setSuccess(true);
				resultBean.setObject(result.getObject());
			} else {
				productTime = (int) result.getObject();
				ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
				if (nextResult.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(nextResult.getObject());
				} else {
					resultBean.setSuccess(false);
					resultBean.setMessage("无法获取下线时间");
				}
			}
		} else if (listShifts.size() == 2) {
			// 双班次默认是连续的
			/**
			 * 双班次： (1)07:00--19:00 (2)19:00--07:00 (1)08:00--20:00
			 * (2)20:00--08:00 (1)07:00--16:00 (2)16:00--01:00 (1)07:00--15:00
			 * (2)15:00--23:00
			 */

			Shift shift1 = listShifts.get(0);
			LocalTime shift1Start = shift1.getInnnerData().getStartTime();
			LocalTime shift1End = shift1.getInnnerData().getEndTime();
			LocalDateTime shift1StartTime = LocalDateTime.of(localDate, shift1Start);
			LocalDateTime shift1EndTime = LocalDateTime.of(localDate, shift1End);
			// 理论不存在
			if (shift1EndTime.isBefore(shift1StartTime)) {
				resultBean.setSuccess(false);
				resultBean.setMessage(localDate + "首班次跨天!");
				return resultBean;
			}

			Shift shift2 = listShifts.get(1);
			LocalTime shift2Start = shift2.getInnnerData().getStartTime();
			LocalTime shift2End = shift2.getInnnerData().getEndTime();
			LocalDateTime shift2StartTime = LocalDateTime.of(localDate, shift2Start);
			LocalDateTime shift2EndTime = LocalDateTime.of(localDate, shift2End);
			// 第二班次存在跨天的可能性
			if (shift2EndTime.isBefore(shift2StartTime)) {
				shift2EndTime = shift2EndTime.plusDays(1);
			}

			// 第一个班次，开始生产
			ResultBean result = getOfflineFromShift(shift1, shift1StartTime, shift1EndTime, shift1StartTime,
					productTime);
			if (result.isSuccess()) {
				resultBean.setSuccess(true);
				resultBean.setObject(result.getObject());
			} else {
				productTime = (int) result.getObject();
				ResultBean result2 = getOfflineFromShift(shift2, shift2StartTime, shift2EndTime, shift2StartTime,
						productTime);
				if (result2.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(result2.getObject());
				} else {
					productTime = (int) result2.getObject();
					ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
					if (nextResult.isSuccess()) {
						resultBean.setSuccess(true);
						resultBean.setObject(nextResult.getObject());
					} else {
						resultBean.setSuccess(false);
						resultBean.setMessage("无法获取下线时间");
					}
				}
			}

		} else if (listShifts.size() == 3) {
			/**
			 * 三班次： (1)08:00--16:00 (2)16:00--00:00 (3)00:00--08:00
			 * (1)00:00--08:00 (2)08:00--16:00 (3)16:00--00:00
			 */

			Shift shift1 = listShifts.get(0);
			LocalTime shift1Start = shift1.getInnnerData().getStartTime();
			LocalTime shift1End = shift1.getInnnerData().getEndTime();
			LocalDateTime shift1StartTime = LocalDateTime.of(localDate, shift1Start);
			LocalDateTime shift1EndTime = LocalDateTime.of(localDate, shift1End);
			// 理论不存在
			if (shift1EndTime.isBefore(shift1StartTime)) {
				resultBean.setSuccess(false);
				resultBean.setMessage(localDate + "首班次跨天!");
				return resultBean;
			}

			Shift shift2 = listShifts.get(1);
			LocalTime shift2Start = shift2.getInnnerData().getStartTime();
			LocalTime shift2End = shift2.getInnnerData().getEndTime();
			LocalDateTime shift2StartTime = LocalDateTime.of(localDate, shift2Start);
			LocalDateTime shift2EndTime = LocalDateTime.of(localDate, shift2End);
			// 第二班次存在跨天的可能性
			if (shift2EndTime.isBefore(shift2StartTime)) {
				shift2EndTime = shift2EndTime.plusDays(1);
			}

			Shift shift3 = listShifts.get(2);
			LocalTime shift3Start = shift3.getInnnerData().getStartTime();
			LocalTime shift3End = shift3.getInnnerData().getEndTime();
			LocalDateTime shift3StartTime = LocalDateTime.of(localDate, shift3Start);
			LocalDateTime shift3EndTime = LocalDateTime.of(localDate, shift3End);

			// 判断第三班次开始时间是否小于第二班次开始时间
			if (shift3StartTime.isBefore(shift2StartTime)) {
				shift3StartTime = shift3StartTime.plusDays(1);
			}

			// 第三班次存在跨天的可能性
			if (shift3EndTime.isBefore(shift3StartTime)) {
				shift3EndTime = shift3EndTime.plusDays(1);
			}

			// 第一个班次，开始生产

			ResultBean result = getOfflineFromShift(shift1, shift1StartTime, shift1EndTime, shift1StartTime,
					productTime);
			if (result.isSuccess()) {
				resultBean.setSuccess(true);
				resultBean.setObject(result.getObject());
			} else {
				productTime = (int) result.getObject();
				// 第2个班次继续生产
				ResultBean result2 = getOfflineFromShift(shift2, shift2StartTime, shift2EndTime, shift2StartTime,
						productTime);
				if (result2.isSuccess()) {
					resultBean.setSuccess(true);
					resultBean.setObject(result2.getObject());
				} else {
					productTime = (int) result2.getObject();
					// 第三个班次继续生产
					ResultBean result3 = getOfflineFromShift(shift3, shift3StartTime, shift3EndTime, shift3StartTime,
							productTime);
					if (result3.isSuccess()) {
						resultBean.setSuccess(true);
						resultBean.setObject(result3.getObject());
					} else {
						productTime = (int) result.getObject();
						// 下一个班次继续生产
						ResultBean nextResult = getOfflineFromNextDate(lineId, localDate.plusDays(1), productTime);
						if (nextResult.isSuccess()) {
							resultBean.setSuccess(true);
							resultBean.setObject(nextResult.getObject());
						} else {
							resultBean.setSuccess(false);
							resultBean.setMessage("无法获取下线时间");
						}
					}
				}
			}
		}
		return resultBean;
	}

	public ResultBean getOfflineFromShift(Shift shift, LocalDateTime shiftStartTime, LocalDateTime shiftEndTime,
			LocalDateTime scheudledOnlineDate, int productTime) {
		ResultBean resultBean = new ResultBean(true, "");
		LocalDate localDate = shiftStartTime.toLocalDate();

		Duration between = java.time.Duration.between(scheudledOnlineDate, shiftEndTime);
		long shiftMins = between.toMinutes(); // 剩余班次总时长，单位分钟

		List<ShiftItem> shiftItems = shift.getShiftItems();
		int rest = 0; // 休息总时长

		for (ShiftItem item : shiftItems) {
			if ("REST".equals(item.getInnerEntity().getShiftItemType())) {

				LocalTime itemStart = item.getInnerEntity().getStartTime();
				LocalTime itemEnd = item.getInnerEntity().getEndTime();

				LocalDateTime shiftItemStart = LocalDateTime.of(localDate, itemStart);
				if (shiftItemStart.isBefore(shiftStartTime)) {
					shiftItemStart = shiftItemStart.plusDays(1);
				}
				LocalDateTime shiftItemEnd = LocalDateTime.of(localDate, itemEnd);
				if (shiftItemEnd.isBefore(shiftStartTime)) {
					shiftItemEnd = shiftItemEnd.plusDays(1);
				}

				if (shiftItemStart.isAfter(scheudledOnlineDate)) {
					rest += item.getInnerEntity().getDuration();
				} else {
					if (shiftItemEnd.isAfter(scheudledOnlineDate)) {
						Duration between2 = java.time.Duration.between(scheudledOnlineDate, shiftItemEnd);
						long minutes = between2.toMinutes();
						rest += minutes;
					}
				}
			}
		}
		long shiftWork = shiftMins - rest;// 剩余工作总时长

		if (shiftWork >= productTime) {
			LocalDateTime offlineDateTime = scheudledOnlineDate.plusMinutes(productTime);// 理论下线
			// 添加休息时间
			for (ShiftItem item : shiftItems) {
				if ("REST".equals(item.getInnerEntity().getShiftItemType())) {
					LocalTime startTime2 = item.getInnerEntity().getStartTime();
					LocalDateTime shiftItemStart = LocalDateTime.of(localDate, startTime2);
					if (shiftItemStart.isBefore(shiftStartTime)) {
						shiftItemStart = shiftItemStart.plusDays(1);
					}
					if (shiftItemStart.isAfter(scheudledOnlineDate) && shiftItemStart.isBefore(offlineDateTime)) {
						offlineDateTime = offlineDateTime.plusHours(item.getInnerEntity().getDuration());
					}
				}
			}
			resultBean.setSuccess(true);
			resultBean.setObject(offlineDateTime);

		} else {
			productTime = productTime - (int) shiftWork;
			resultBean.setSuccess(false);
			resultBean.setObject(productTime);
		}
		return resultBean;
	}

}
